/**
 * 文件名：YfSerialPortListener.java
 *
 * 创建人：Elvin Zhao - 279152260@qq.com
 *
 * 创建时间：2018年7月19日 上午1:01:41
 *
 * 版权所有：FNII
 */
package com.springvision.yuanfeng.core;

import java.io.IOException;
import java.util.TooManyListenersException;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jeeplus.common.utils.text.EncodeUtil;
import com.springvision.core.serialport.AbstractSerialPortListener;
import com.springvision.core.serialport.SerialPortUtils;
import com.springvision.yuanfeng.device.entity.Device;
import com.springvision.yuanfeng.device.entity.DeviceMessage;
import com.springvision.yuanfeng.device.service.DeviceMessageService;
import com.springvision.yuanfeng.device.service.DeviceService;
import com.springvision.yuanfeng.device.service.DeviceStatService;
import com.springvision.yuanfeng.device.web.SerialPortController;
import com.springvision.yuanfeng.locale.service.DevStationService;
import com.springvision.yuanfeng.weather.entity.Weather;
import com.springvision.yuanfeng.weather.service.WeatherService;

import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.UnsupportedCommOperationException;

/**
 * [描述信息：说明类的基本功能]
 *
 * @author Elvin Zhao - 279152260@qq.com
 * @version 1.0 Created on 2018年7月19日 上午1:01:41
 */
@Service
public class YfSerialPortListener extends AbstractSerialPortListener {

	@Autowired
	private DeviceService deviceService;

	@Autowired
	private DeviceMessageService deviceMessageService;

	@Autowired
	private WeatherService weatherService;

	@Autowired
	private DevStationService devStationService;

	@Autowired
	private DeviceStatService deviceStatService;

	/**
	 * 给入库缓存用
	 */
	private static StringBuffer msgBuffer = new StringBuffer(100);

	public YfSerialPortListener(CommPortIdentifier port) {
		this.port = port;
	}

	public YfSerialPortListener() {
		super();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.springvision.core.serialport.AbstractSerialPortListener#onReceive()
	 * @author: Elvin Zhao - 279152260@qq.com
	 * @date: Created on 2018年7月19日 上午1:01:41
	 */
	@Override
	protected void onReceive() {
		try {
			// TODO 修改部分，供参考
			byte[] readBuffer = new byte[1024];
			String msg = "";
			int bufflenth = is.available();
			while (bufflenth != 0) {
				// 初始化byte数组为buffer中数据的长度
				readBuffer = new byte[bufflenth];
				is.read(readBuffer);
				bufflenth = is.available();
			}
			msg = EncodeUtil.bytesToHexString(readBuffer);
			msgBuffer.append(msg);
			System.err.println("原始串口报文----->>>" + msg);
			// System.err.println("msgBuffer报文----->>>" + msgBuffer);
			String four_tail_Buff = "";
			String eight_tail_Buff = "";
			while (msgBuffer.indexOf(SerialPortProtocol._FRAME_HEADER) >= 0) {
				// 剪掉起始符之前的数据
				msgBuffer.delete(0, msgBuffer.indexOf(SerialPortProtocol._FRAME_HEADER));
				int startIndex = msgBuffer.indexOf(SerialPortProtocol._FRAME_HEADER);

				four_tail_Buff = msgBuffer.substring(startIndex + 16, startIndex + 20);
				eight_tail_Buff = msgBuffer.substring(startIndex + 24, startIndex + 28);
				if (four_tail_Buff.indexOf(SerialPortProtocol._FRAME_TAIL) >= 0) {

					int endIndex = startIndex + 20;
					String frame = "";
					if (startIndex > -1) {// 出现结束标识符表示一条指令接收完整
						frame = msgBuffer.substring(startIndex, endIndex);// 取出结束标识符前的数据

						msgBuffer.delete(startIndex, endIndex);

						System.err.println("完整数据帧-----<<<" + frame);
						intoDB(frame);

					}
				} else if (eight_tail_Buff.indexOf(SerialPortProtocol._FRAME_TAIL) >= 0) {

					int endIndex = startIndex + 28;
					String frame = "";
					if (startIndex > -1) {// 出现结束标识符表示一条指令接收完整
						frame = msgBuffer.substring(startIndex, endIndex);// 取出结束标识符前的数据
						msgBuffer.delete(startIndex, endIndex);
						System.err.println("完整数据帧-----<<<" + frame);
						intoDB(frame);

					}
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void intoDB(String frame) {
		String frameModule = StringUtils.substring(frame, 0, 6);
		switch (frameModule) {
		case SerialPortProtocol._FR_MODULE_WATER_LEVEL:
			// System.out.println("frame---water---" + frame);
			SerialPortProtocol serialPortProtocol = new SerialPortProtocol(frame);
			// System.out.println("water---" + serialPortProtocol.toString());
			this.saveWater(serialPortProtocol);
			break;
		case SerialPortProtocol._FR_MODULE_WEATHER:
			this.saveWeather(frame);
			break;
		default:
			break;
		}
		// }
	}

	/**
	 * 串口协议转化设备消息入库 此处判断缓存是否执行设备插入
	 * 
	 * @param spp
	 * @author: Elvin Zhao - 279152260@qq.com
	 * @date: Created on 2018年7月17日 下午9:05:49
	 */
	private void saveWater(SerialPortProtocol spp) {
		DeviceMessage deviceMessage = spp.transformer();

		/**
		 * 1.缓存里不存在的dev，先写入设备表，写入设备表的同时写入缓存 2.判断缓存中消息是否更新，消息加入devid，并入库
		 */
		if (!SerialPortController._DEVICE_CACHE.containsKey(deviceMessage.getDeviceCode())) {
			Device dev = deviceMessage.getDevice();
			dev.setDevStation(devStationService.findOneStation());
			deviceService.saveOffline(dev);
		}

		Device dev = SerialPortController._DEVICE_CACHE.get(deviceMessage.getDeviceCode());
		if (dev.getId() != null) {
			Integer num = deviceStatService.getDeviceReportCount(dev.getId());
			if (num.equals(0)) {
				deviceMessage.setDeviceId(dev.getId());
				deviceMessageService.save(deviceMessage);
			}
		}

	}

	/**
	 * 
	 * 气象模块写入方法 气候表有且只有一条数据 需要获取场站id
	 * 
	 * @param frame
	 * @author: Elvin Zhao - 279152260@qq.com
	 * @date: Created on 2018年7月29日 下午3:40:40
	 */
	private void saveWeather(String frame) {
		// Weather oldWeather = weatherService.getOne();
		Weather oldWeather = weatherService.get("1");
		// Weather oldWeather = null;
		// System.err.println("oldWeather----" + oldWeather);
		Weather weather = new Weather(oldWeather, frame);
		System.err.println(weather.toString());
		weatherService.save(weather);

	}

	public void start()
			throws IOException, UnsupportedCommOperationException, TooManyListenersException, PortInUseException {
		System.err.println("---------------------------------------------------");
		System.err.println("---------------------------------------------------");
		System.err.println("---------------------------------------------------");
		System.err.println("---------------------------------------------------");
		System.err.println("---------------------------------------------------");
		// COM1串口发送数据，在COM2--串口调试工具 接收数据
		// 监听串口COM2读
		CommPortIdentifier port = SerialPortUtils.getSerialPort("COM2");
		System.out.println(port.getName());
		YfSerialPortListener listener = new YfSerialPortListener(port);
		listener.initAndOpen();

	}

	public static void main(String[] args)
			throws IOException, UnsupportedCommOperationException, TooManyListenersException, PortInUseException {
		System.err.println("---------------------------------------------------");
		System.err.println("---------------------------------------------------");
		System.err.println("---------------------------------------------------");
		System.err.println("---------------------------------------------------");
		System.err.println("---------------------------------------------------");
		// COM1串口发送数据，在COM2--串口调试工具 接收数据
		// 监听串口COM2读
		CommPortIdentifier port = SerialPortUtils.getSerialPort("COM2");
		 System.out.println(port.getName());
		YfSerialPortListener listener = new YfSerialPortListener(port);
		listener.initAndOpen();
	}

}
